#include "texture.h"

Texture::Texture(const char* filename, bool hasAlpha)
{
    _pixels = NULL;
    _id = 0;
    _width = 0;
    _height = 0;
    _hasAlpha = hasAlpha;

    read(filename, hasAlpha);
    upload();
}

Texture::~Texture()
{
    if (_pixels != NULL) {
        delete[] _pixels;
    }

    glDeleteTextures(1, (GLuint*)&_id);
}

void Texture::read(const char* filename, bool hasAlpha)
{
    png::image<png::rgba_pixel> image(filename);

    int w = image.get_width();
    int h = image.get_height();

    _width = w;
    _height = h;
    _pixels = new char[w * h * 4];

    int index = 0;
    for (int y = h - 1; y >= 0; --y) {
        png::image<png::rgba_pixel>::row_type row = image.get_row(y);
        for (int x = 0; x < w; ++x) {
            png::rgba_pixel pixel = row.at(x);
            _pixels[index++] = pixel.red;
            _pixels[index++] = pixel.green;
            _pixels[index++] = pixel.blue;
            if (hasAlpha) {
                _pixels[index++] = pixel.alpha;
            } else {
                _pixels[index++] = 255;
            }
        }
    }
}

void Texture::upload()
{
    glGenTextures(1, (GLuint*)&_id);
    glBindTexture(GL_TEXTURE_2D, _id);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                     GL_LINEAR_MIPMAP_NEAREST);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    gluBuild2DMipmaps(GL_TEXTURE_2D, 4, _width, _height, GL_RGBA,
                      GL_UNSIGNED_BYTE, _pixels);
    glBindTexture(GL_TEXTURE_2D, 0);
}


int Texture::getId() const
{
    return _id;
}

int Texture::getWidth() const
{
    return _width;
}

int Texture::getHeight() const
{
    return _height;
}

bool Texture::hasAlpha()
{
    return _hasAlpha;
}
